package oauth

import (
    "fmt"
	"errors"
	"wxsdk/miniapp/core"
	//"github.com/astaxie/beego"
)
// 获取第三方平台component_access_token (刷新也是此方法)
type AccessTokenResponseResult struct {
	*core.ErrorResponse
	*AccessTokenResponse
}
type AccessTokenResponse struct {
	Token     string `json:"component_access_token"`
	ExpiresIn int64  `json:"expires_in"`        // 有效时间, seconds
}
func  GetIsvToken(isvAppId,isvAppSecret,ticket string)(string, int64, error){
	client := core.GetPostJSONClient()
	var rsp AccessTokenResponseResult
	request := struct {
		AppId        string `json:"component_appid"`
		AppSecret    string `json:"component_appsecret"`
		VerifyTicket string `json:"component_verify_ticket"`
	}{
		AppId: isvAppId,
		AppSecret: isvAppSecret,
		VerifyTicket: ticket,
	}
	serverUrl := "https://api.weixin.qq.com/cgi-bin/component/api_component_token"
	tbdata, err := client.Excute("POST", serverUrl, request, &rsp)
    if err != nil {
		//beego.Critical(err.Error())
		return "", 0, err
	}
	if rsp.ErrorResponse != nil {
		//beego.Critical("error:", string(tbdata))
		return "", 0, errors.New(string(tbdata)) 
	}
	return rsp.AccessTokenResponse.Token,rsp.AccessTokenResponse.ExpiresIn,nil
}

// 获取预授权码
type PreAuthCodeResponseResult struct {
	*core.ErrorResponse
	*PreAuthCodeResponse
}
type PreAuthCodeResponse struct {
	PreAuthCode  string `json:"pre_auth_code"`
	ExpiresIn    int64  `json:"expires_in"`        // 有效时间, seconds
}
func  GetPreAuthCode(isvAppId,isvAccessToken string)(string, int64, error){
	client := core.GetPostJSONClient()
	var rsp PreAuthCodeResponseResult
	request := struct {
		ComponentAppId string `json:"component_appid"`
	}{
		ComponentAppId: isvAppId,
	}
	serverUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=%s",isvAccessToken)
	tbdata, err := client.Excute("POST", serverUrl, request, &rsp)
    if err != nil {
		//beego.Critical(err.Error())
		return "", 0, err
	}
	if rsp.ErrorResponse != nil {
		//beego.Critical("error:", string(tbdata))
		return "", 0, errors.New(string(tbdata)) 
	}
	return rsp.PreAuthCodeResponse.PreAuthCode,rsp.PreAuthCodeResponse.ExpiresIn,nil
}

//  4、使用授权码换取公众号或小程序的接口调用凭据和授权信息
type QueryAuthResponseResult struct {
	*core.ErrorResponse         //只所以定义为指针，为了和nil比较
	QueryAuthResponse           //也可以定义为指针，应该都可以解析出来
}
type QueryAuthResponse struct {
	AuthorizationInfo struct {
		AuthorizerAppid string `json:"authorizer_appid"`
		AccessToken     string `json:"authorizer_access_token"`
		ExpiresIn       int    `json:"expires_in"`
	    RefreshToken    string `json:"authorizer_refresh_token"`
		FuncInfo []struct {
			Funcscope struct {
				Id int64 `json:"id"`
			} `json:"funcscope_category"`
		} `json:"func_info"`
	} `json:"authorization_info"`
}

func  ApiQueryAuth(isvAppId,isvAccessToken,code string)(QueryAuthResponse, error){
	client := core.GetPostJSONClient()
	var rsp QueryAuthResponseResult
	request := struct {
		ComponentAppid    string `json:"component_appid"`
	    AuthorizationCode string `json:"authorization_code"`
	}{
		ComponentAppid: isvAppId,
		AuthorizationCode: code,
	}
	serverUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=%s",isvAccessToken)
	tbdata, err := client.Excute("POST", serverUrl, request, &rsp)
	if err != nil {
		//beego.Debug(err.Error())
		//beego.Debug("error:", string(tbdata))
		return rsp.QueryAuthResponse, err
	}
	//beego.Debug("ApiQueryAuth:", string(tbdata))
	if rsp.ErrorResponse != nil {
		//beego.Debug("error:", string(tbdata))
		return rsp.QueryAuthResponse, errors.New(string(tbdata)) 
	}
	return rsp.QueryAuthResponse,nil
}

// 5、获取（刷新）授权公众号或小程序的接口调用凭据（令牌）
type AuthorizerTokenResponseResult struct {
	*core.ErrorResponse
	*AuthorizerTokenResponse
}
type AuthorizerTokenResponse struct {
	AccessToken  string `json:"authorizer_access_token"`
	ExpiresIn    int    `json:"expires_in"`
	RefreshToken string `json:"authorizer_refresh_token"`
}
func  RefreshAuthorizerToken(isvAppId,isvAccessToken,authorizerAppId,refreshToken string)(string,string,int,error){
	client := core.GetPostJSONClient()
	var rsp AuthorizerTokenResponseResult
	request := struct {
		ComponentAppid         string `json:"component_appid"`
		AuthorizerAppid        string `json:"authorizer_appid"`
		AuthorizerRefreshToken string `json:"authorizer_refresh_token"`
	}{
		ComponentAppid: isvAppId,
		AuthorizerAppid: authorizerAppId,
		AuthorizerRefreshToken: refreshToken,
	}
	serverUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=%s",isvAccessToken)
	tbdata, err := client.Excute("POST", serverUrl, request, &rsp)
    if err != nil {
		//beego.Critical(err.Error())
		return "","",0,err
	}
	if rsp.ErrorResponse != nil {
		//beego.Critical("app_id error:", authorizerAppId, string(tbdata))
		return "","",0,errors.New(string(tbdata)) 
	}
	return rsp.AuthorizerTokenResponse.AccessToken,rsp.AuthorizerTokenResponse.RefreshToken,rsp.AuthorizerTokenResponse.ExpiresIn,nil
}

// 6、获取授权方的帐号基本信息
type GetAuthorizerInfoResponseResult struct {
	*core.ErrorResponse
	GetAuthorizerInfoResponse
}
type MiniProgramInfo struct {
	Network struct {
		RequestDomain []string `json:"RequestDomain"`
		WsRequestDomain []string `json:"WsRequestDomain"`
		UploadDomain []string `json:"UploadDomain"`
		DownloadDomain []string `json:"DownloadDomain"`
	} `json:"network"`
	Categories []struct {
		First  string `json:"first"`
		Second string `json:"second"`
		
		
	} `json:"categories"`
	VisitStatus int `json:"visit_status"`
}	
type GetAuthorizerInfoResponse struct {
	AuthorizerInfo struct {
		NickName        string `json:"nick_name"`
		HeadImg         string `json:"head_img"`
		ServiceTypeInfo struct {
			Id int `json:"id"`
		} `json:"service_type_info"`
		VerifyTypeInfo struct {
			Id int `json:"id"`
		} `json:"verify_type_info"`
		UserName       string `json:"user_name"`
		Alias          string `json:"alias"`
		QrcodeUrl      string `json:"qrcode_url"`
		BusinessInfo  struct {
			OpenStore int `json:"open_store"`
			OpenScan  int `json:"open_scan"`
			OpenPay   int `json:"open_pay"`
			OpenCard  int `json:"open_card"`
			OpenShake int `json:"open_shake"`
		} `json:"business_info"`
		Idc            int    `json:"idc"`
		PrincipalName  string `json:"principal_name"`
		Signature      string `json:"signature"`
	    MiniProgramInfo *MiniProgramInfo `json:"MiniProgramInfo"`   //小程序独有的结构
	} `json:"authorizer_info"`
	AuthorizationInfo struct {
		AuthorizerAppid    string `json:"authorizer_appid"`
		FuncInfo []struct {
			FuncScope struct {
				Id int64 `json:"id"`
			} `json:"funcscope_category"`
		} `json:"func_info"`
	} `json:"authorization_info"`
}
func  GetAuthorizerInfo(isvAppId,isvAccessToken,authorizerAppId string)(GetAuthorizerInfoResponse, error){
	client := core.GetPostJSONClient()
	var rsp GetAuthorizerInfoResponseResult
	request := struct {
		ComponentAppid    string `json:"component_appid"`
	    AuthorizerAppid   string `json:"authorizer_appid"`
	}{
		ComponentAppid: isvAppId,
		AuthorizerAppid: authorizerAppId,
	}
	serverUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=%s",isvAccessToken)
	tbdata, err := client.Excute("POST", serverUrl, request, &rsp)
    if err != nil {
		//beego.Critical(err.Error())
		return rsp.GetAuthorizerInfoResponse, err
	}
	//beego.Debug("GetAuthorizerInfo:", string(tbdata))
	if rsp.ErrorResponse != nil {
		//beego.Critical("error:", string(tbdata))
		return rsp.GetAuthorizerInfoResponse, errors.New(string(tbdata)) 
	}
	return rsp.GetAuthorizerInfoResponse,nil
}

